import 'package:flutter/material.dart';
import 'dart:math' as math;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 动画综合示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const AnimationHomePage(),
      routes: {
        '/scale': (context) => const ScaleAnimationRoute(),
        '/fadeRoute': (context) => const FadeRoutePage(),
        '/stagger': (context) => const StaggerRoute(),
        '/switcher': (context) => const AnimatedSwitcherCounterRoute(),
      },
    );
  }
}

class AnimationHomePage extends StatelessWidget {
  const AnimationHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter 动画综合示例')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/scale'),
              child: const Text('基础动画示例'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.push(
                context,
                FadeRoute(builder: (context) => const FadeRoutePage()),
              ),
              child: const Text('自定义路由切换'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/stagger'),
              child: const Text('交织动画示例'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/switcher'),
              child: const Text('AnimatedSwitcher示例'),
            ),
          ],
        ),
      ),
    );
  }
}

// 1. 基础动画示例
class ScaleAnimationRoute extends StatefulWidget {
  const ScaleAnimationRoute({super.key});

  @override
  State<ScaleAnimationRoute> createState() => _ScaleAnimationRouteState();
}

class _ScaleAnimationRouteState extends State<ScaleAnimationRoute>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;
  late Animation<double> animation;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    );

    // 使用弹性曲线
    final curvedAnimation = CurvedAnimation(
      parent: controller,
      curve: Curves.bounceOut,
    );

    // 图片宽高从0变到300
    animation = Tween(begin: 0.0, end: 300.0).animate(curvedAnimation)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          controller.reverse();
        } else if (status == AnimationStatus.dismissed) {
          controller.forward();
        }
      })
      ..addListener(() {
        setState(() {});
      });

    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('基础动画示例')),
      body: Center(
        child: Image.asset(
          'assets/flutter_logo.png',
          width: animation.value,
          height: animation.value,
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

// 2. 自定义路由切换
class FadeRoute extends PageRoute {
  FadeRoute({
    required this.builder,
    this.transitionDuration = const Duration(milliseconds: 500),
    this.opaque = true,
    this.barrierDismissible = false,
    this.barrierColor,
    this.barrierLabel,
    this.maintainState = true,
  });

  final WidgetBuilder builder;

  @override
  final Duration transitionDuration;

  @override
  final bool opaque;

  @override
  final bool barrierDismissible;

  @override
  final Color? barrierColor;

  @override
  final String? barrierLabel;

  @override
  final bool maintainState;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation) {
    return builder(context);
  }

  @override
  Widget buildTransitions(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation, Widget child) {
    // 当前路由被激活，是打开新路由
    if (isActive) {
      return FadeTransition(
        opacity: animation,
        child: child,
      );
    } else {
      // 是返回，则不应用过渡动画
      return child;
    }
  }
}

class FadeRoutePage extends StatelessWidget {
  const FadeRoutePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('自定义路由切换')),
      body: const Center(
        child: Text(
          '这是一个使用渐隐渐入效果的路由',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

// 3. 交织动画示例
class StaggerRoute extends StatefulWidget {
  const StaggerRoute({super.key});

  @override
  State<StaggerRoute> createState() => _StaggerRouteState();
}

class _StaggerRouteState extends State<StaggerRoute>
    with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 2000),
      vsync: this,
    );
  }

  Future<void> _playAnimation() async {
    try {
      await _controller.forward().orCancel;
      await _controller.reverse().orCancel;
    } on TickerCanceled {
      // 捕获异常
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('交织动画示例')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => _playAnimation(),
              child: const Text("开始动画"),
            ),
            const SizedBox(height: 20),
            Container(
              width: 300.0,
              height: 300.0,
              decoration: BoxDecoration(
                color: Colors.black.withOpacity(0.1),
                border: Border.all(
                  color: Colors.black.withOpacity(0.5),
                ),
              ),
              child: StaggerAnimation(controller: _controller),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

class StaggerAnimation extends StatelessWidget {
  StaggerAnimation({
    super.key,
    required this.controller,
  }) {
    // 高度动画
    height = Tween<double>(begin: 0.0, end: 300.0).animate(
      CurvedAnimation(
        parent: controller,
        curve: const Interval(0.0, 0.6, curve: Curves.ease),
      ),
    );

    // 颜色动画
    color = ColorTween(begin: Colors.green, end: Colors.red).animate(
      CurvedAnimation(
        parent: controller,
        curve: const Interval(0.0, 0.6, curve: Curves.ease),
      ),
    );

    // 内边距动画
    padding = Tween<EdgeInsets>(
      begin: const EdgeInsets.only(left: 0.0),
      end: const EdgeInsets.only(left: 100.0),
    ).animate(
      CurvedAnimation(
        parent: controller,
        curve: const Interval(0.6, 1.0, curve: Curves.ease),
      ),
    );
  }

  late final Animation<double> controller;
  late final Animation<double> height;
  late final Animation<Color?> color;
  late final Animation<EdgeInsets> padding;

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: controller,
      builder: (context, child) {
        return Container(
          alignment: Alignment.bottomCenter,
          padding: padding.value,
          child: Container(
            color: color.value,
            width: 50.0,
            height: height.value,
          ),
        );
      },
    );
  }
}

// 4. AnimatedSwitcher示例
class AnimatedSwitcherCounterRoute extends StatefulWidget {
  const AnimatedSwitcherCounterRoute({super.key});

  @override
  State<AnimatedSwitcherCounterRoute> createState() =>
      _AnimatedSwitcherCounterRouteState();
}

class _AnimatedSwitcherCounterRouteState
    extends State<AnimatedSwitcherCounterRoute> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('AnimatedSwitcher示例')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            AnimatedSwitcher(
              duration: const Duration(milliseconds: 500),
              transitionBuilder: (Widget child, Animation<double> animation) {
                // 使用自定义的SlideTransitionX实现左右滑动效果
                return SlideTransitionX(
                  child: child,
                  direction: AxisDirection.left,
                  position: animation,
                );
              },
              child: Text(
                '$_count',
                key: ValueKey<int>(_count),
                style: Theme.of(context).textTheme.displaySmall,
              ),
            ),
            const SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  child: const Text('+1'),
                  onPressed: () {
                    setState(() {
                      _count += 1;
                    });
                  },
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  child: const Text('-1'),
                  onPressed: () {
                    setState(() {
                      _count -= 1;
                    });
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// 自定义的SlideTransition，支持上下左右四个方向
class SlideTransitionX extends AnimatedWidget {
  SlideTransitionX({
    super.key,
    required Animation<double> position,
    this.transformHitTests = true,
    this.direction = AxisDirection.down,
    required this.child,
  }) : super(listenable: position) {
    switch (direction) {
      case AxisDirection.up:
        _tween = Tween(begin: const Offset(0, 1), end: const Offset(0, 0));
      case AxisDirection.right:
        _tween = Tween(begin: const Offset(-1, 0), end: const Offset(0, 0));
      case AxisDirection.down:
        _tween = Tween(begin: const Offset(0, -1), end: const Offset(0, 0));
      case AxisDirection.left:
        _tween = Tween(begin: const Offset(1, 0), end: const Offset(0, 0));
    }
  }

  final bool transformHitTests;
  final Widget child;
  final AxisDirection direction;
  late final Tween<Offset> _tween;

  @override
  Widget build(BuildContext context) {
    final position = listenable as Animation<double>;
    Offset offset = _tween.evaluate(position);
    
    if (position.status == AnimationStatus.reverse) {
      switch (direction) {
        case AxisDirection.up:
          offset = Offset(offset.dx, -offset.dy);
        case AxisDirection.right:
          offset = Offset(-offset.dx, offset.dy);
        case AxisDirection.down:
          offset = Offset(offset.dx, -offset.dy);
        case AxisDirection.left:
          offset = Offset(-offset.dx, offset.dy);
      }
    }
    
    return FractionalTranslation(
      translation: offset,
      transformHitTests: transformHitTests,
      child: child,
    );
  }
}